Problèmes potentiels et solutions

Nous décrivons ici les problèmes que nous avons rencontré à chaque étape et leurs solutions. On suppose que vous avez déjà lu notre texte sur les étapes avec addaccu. Vous pouvez aussi voir le Makefile (le leur et le notre) pour mieux voir l'ordre des opérations.

Ce document ce découpe ainsi :

Simulation

Cette première étape nécessite d'avoir un fichier .vbe correct, et un jeu de tests (.pat). Savoir si le fichier .vbe est synthétisable sera discuté avec l'optimiseur logique bop et avec l'extraction de la netlist. Pour connaître les structures utilisables, il faut voir les pages de manuel vhdl et vbe, ainsi que notre fichier diviseur.vbe et ceux des tutorials ($TOP/tutorials/addaccu/addaccu.vbe, et $TOP/tutorials/amd2901/amd.vbe). Comme il est précisé dans nos commentaires sur addaccu, on peut tester si un fichier est syntaxiquement correct avec "asimut -b -c ...".

Ce qu'il faut d'ores et déjà savoir, c'est qu'il ne faut assigner qu'une seule fois un signal normal, alors que l'on peut théoriquement assigner un signal registre dans plusieurs "blocs", MAIS ATTENTION, nos essais nous ont montré que les problèmes arrivent après (d'après la documentation (vbe), on doit quand même pouvoir le faire avec des "mux_bit", mais avec une utilisation bien particulière).

ATTENTION : Dans certains cas, nous avons trouvé que le test de différence de deux vecteurs (".../=...") n'était pas équivalant à la négation de l'égalité ("not (... = ...)"). Peut-être que le reste du fichier vhdl avait des "bizarreries", mais toujours est-il que toutes choses égales par ailleurs, nous avons eu des différences de simulation en changeant des "/=" en "not ...". La bonne version était avec "not ...". Il faut quand même souligner que nous n'avons pas réussi à reproduire ce phénomène avec un fichier vhdl simple, mais pour plus de sûreté, il vaut peut-être mieux utiliser "not (... = ...)". D'une manière plus générale, dans toutes les étapes, on gagne en résultat et en nombre de cellules si on met des formules de bas niveau.

La simulation utilise un fichier .pat que l'on peut écrire directement ou synthétiser par genpat. Pour cela, voir notre fichier test.c et les pages de manuel pat(5) et genpat. Le résultat peut être vu par waview, xpat ou en éditant le fichier .pat résultant. Ce système de fichier .pat nous a paru très pratique, car on peut générer des tests évolués et même faire des tests "automatiques" en générant le résultat théorique qui sera comparé avec la simulation : on pourrait éviter de visionner les chronogrammes de sortie en calculant les résultats en C.

ATTENTION : Pour éviter de tomber dans le même piège que nous, il ne faut pas se contenter de simuler le fichier d'origine, mais à chaque étape, il faut simuler le fichier .vbe ou .vst obtenu. (ceci est réalisé par notre Makefile générique).

Optimisation logique (bop)

En VHDL, l'utilisation de blocs sur front s'obtient avec la condition de bloc "( (not e'stable) and e='1' )" (0 pour les fronts descendants). On peut rajouter des conditions supplémentaires ou alors n'utiliser comme condition de bloc que : "( not e'stable )". Vous obtiendrez un fichier VHDL simulable par asimut, MAIS bop refuse ce genre de condition de bloc avec un message du style : "VHDL : Error - bad usage of the 'stable' attribut". Il faut savoir que beaucoup de nos problèmes sont venu avec la nécessité de réagir sur fronts montants et sur fronts descendants. Notre solution peut vous aider.

IMPORTANT : Nous avons constaté que des problèmes apparaissaient dès qu'un signal faisant partie d'une condition de bloc pouvait être qualifié de 'ponctuel'. Prenons l'exemple d'un signal nommé condreset qu'un mécanisme quelconque met à 1 et qui se remet à 0 dès que le compteur qui lui est associé est remis à 0. Le compteur se remet à 0 dès que condreset se met à 1. Dans ce cas, le signal condreset se met à 1 pendant un laps de temps très court. Ce cas-là est bien géré puisqu'on a des vérifications qui se croisent et assurent que toutes les actions sont effectués en temps voulus. Mais si d'autres signaux dépendent de condreset, il faut s'assurer que ces signaux ont bien subis les modifications voulues avant d'annuler le signal condreset. En général, il faut surveiller en particulier tout bloc qui contient des instructions pouvant influer sur sa propre condition de bloc.
Une astuce pour créer des resets asynchrones dans un circuit avec horloge : l'aspect visible du circuit, c'est ses sorties. on peut alors créer à l'intérieur un signal s qui se met à 1 si la ligne reset est à 1 et garde cette valeur tant que le circuit ne répond pas au reset (on peut s'apercevoir que le circuit répond au reset si, par exemple, un compteur interne passe à 0). Les sorties, elles, tiennent compte d signal s et, s'il est à 1, prennent comme valeur 0 (ou la valeur 1 si c'est cette valeur qui doit être affichée après un reset). Cette technique permet au reste du circuit d'être programmé de façon tout à fait synchrone avec l'horloge.

Comme il est dit précédemment, il ne faut pas oublier de simuler le résultat de bop.

Il faut savoir aussi qu'il existe une possibilité de paramétrer le type d'optimisation, et d'empêcher l'optimisation de certains signaux pour gagner du temps, mais nous avons assez peu exploré ce système (les fichier .lax).

"mapping" vers les cellules standard (scmap)

Ce qu'il faut garder en tête, c'est que ce n'est pas parce-que bop s'est bien passé que scmap ne va pas vous dire "...no solution...". Ce problème nous est arrivé plusieurs fois. Il vient de la description vhdl.

Comme il est dit précédemment, il ne faut pas oublier de simuler le résultat de scmap (ici, asimut ne prends pas l'option "-b" : on simule un fichier vst : vhdl structurel).

Routage (scr)

À ce niveau, nous n'avons pas eu beaucoup de problèmes. On peut visionner la sortie (fichier .ap) avec graal.

Utilisation de genlib et pads

genlib sert d'une part à dessiner le circuit avec des regroupements de composants personnel et de cellules standard, ce qui est beaucoup utilisé dans les tutoriels (voir aussi la page de manuel sclib pour une liste et celle du nom de la cellule pour chaque cellule), et d'autre part, à connecter les "pads" avec l'intérieur du circuit. Pour cela, nous avons réalisé un programme en Perl nommé creerring (il se trouve dans notre exemple diviseur) qui génère automatiquement le fichier .c (pour genlib) (et en espérant qu'il fonctionne dans le plus de cas possibles).

Si on fait la connection avec les pads à la main (et non avec notre creerring), il faut procéder comme suit. Pour un circuit avec horloge, il faut s'inspirer des tutoriels (addaccu.c par exemple, ou notre version autogénérée), mais sans horloge, nous avons demandé conseils et nous avons mis une entrée fictive (nommée clk) pour l'horloge (voir le diviseur.c autogénéré par notre programme), qui sera reliée à vdd. Dans ces fichiers, il faut faire attention aux noms et à leur ordre (voir les exemples). Il faut choisir les noms des pads de la même façon qu'à l'étape suivante dans ring.

Remarque : le fichier généré par genlib est un (ou des) fichier(s) .vst .

Obtention de la couche "physique" avec les pads

Comme il l'a été précisé dans notre description de addaccu, on réalise cette étape avec ring. Elle se sert du résultat de la connection avec les pads dans genlib (voir paragraphe précédent), et d'un fichier .rin (voir la page de manuel et les exemples) décrivant les emplacements des pads. Si vous utilisez notre programme d'autogénération du fichier genlib pour les pads, un signal nommé "x" dans la description de l'entité VHDL peut être adressé dans le fichier .rin par le nom du pad qui le contrôle. Ce nom est le nom du signal préfixé par "p_" (donc ici "p_x"). Le pad se trouve en face de la broche du circuit, donc la position du signal "x" est celle du pad "p_x". Notre version du tutorial addaccu indique la syntaxe de ce fichier. Il ne faut pas oublier les lignes d'alimentation "p_vdde","p_vsse","p_vdd","p_vss" et l'horloge "p_clk", qu'elle soit fictive ou non.

Les premières erreurs que nous avons eu venaient du fichier genlib : cela ne devrait pas arriver avec notre programme qui les autogénère. Si vous le faîtes à la main, regardez bien quoi mettre pour les "classes", "instances", et vérifiez que toutes les broches sont connectées.

Les broches d'alimentations internes doivent être d'autant plus proches du centre de leur côté(EST,OUEST,SUD ou NORD) que le circuit est petit.

ATTENTION ! Un autre problème peut apparaître (il nous a fait perdre beaucoup de temps...), mais ses conséquences arrivent après (lors l'extraction). Si vous voyez des erreurs avec yagle (dans un fichier .rep), indiquant que des broches ne sont pas connectées, c'est qu'il faut changer le placement des broches. Nous avons eu ce problème en placant des broches sur deux côtés seulement, mais peut-être qu'il peut apparaître aussi avec un mauvais placement. Pour nous, il a disparu en mettant des broches sur au moins trois côtés.

Extraction de la netlist, et retour au vhdl

L'extraction de la netliste se fait avec lynx. On obtient un fichier .al. Ensuite, on retourne au vbe par yagle. Il faut rappeler ici que le problème précédent avec (ring) peut apparaître ici. C'est la partie avec yagle qui est la plus problématique.

Pour yagle, on procède en deux étapes. D'abord, on n'utilise pas de fichier .inf (voir page de manuel) et on n'utilise pas l'option "-i". Après cette étape, on peut déjà simuler le fichier .vbe obtenu et il doit absolument fonctionner sans "driver conflict" et avec la bonne sortie... On peut éventuellement voir des signaux non assignés, ce qui empêche la simulation (et qui tient bug ? ou d'une optimisation ?)... Pour éviter ce problème, quand il est apparu, nous avons assigné à "1" partout (au lieux de 0) un cas other dans le fichier vbe du début.

Cette étape ne renomme pas les signaux internes. Quand elle fonctionne, on peut renommer les signaux internes en éditant un fichier .inf (voir page de manuel) et en lançant yagle avec l'option "-i". En fait, notre programme Perl prepareproof (voir l'exemple du diviseur de fréquence) autogénère le fichier .inf (mais ATTENTION : avec ce programme, dans le fichier .vbe initial, il ne faut pas terminer un nom de registre par "_" suivi d'un nombre) : la suite de ce paragraphe n'est utile que s'il ne fonctionne pas dans votre contexte. Les signaux à renommer sont les registres. Avec la synthèse vhdl, il prennent des noms en liaison avec les différentes étapes, et avec leur nature (bascule, verroux ...). On peut voir leur nouveau nom dans les REMARQUES du fichier .vbe obtenu. On peut utiliser des caractères génériques pour les vecteurs. Par exemple, la ligne du fichier diviseure.inf "core.compteur_*.dff_s : compteur(*);" transforme tous les bits de "compteur" ayant comme nom (dans le fichier .al, et marqué dans les remarques du fichier .vbe extrait) ce qui est avant les ":" avec un numéro à la place du "*" en le nom qu'il ont dans le fichier .vbe d'origine : "compteur(...)".

Ce renommage permet d'utiliser le prouveur logique proof qui dira si le fichier .vbe "extrait" de la couche physique est "identique" au fichier .vbe d'origine. En fait, comme il a été dit dans la partie précédente, il faut rajouter les alimentations dans le fichier vbe d'origine (nous faisons ce rajout automatiquement : avec prepareproof )
On utilise les scripts Perl dans le cadre du Makefile générique utilisé dans l'exemple du diviseur.

Couche physique réelle

Pour pouvoir obtenir une couche physique réelle, il faut d'abord lancer des druc sur les couches physiques "génériques" (les .ap) pour vérifier les règles de dessin. Nous avons pas eu de problèmes avec les options par défaut. Par contre, on peut utiliser plusieurs technologies avec la variable d'environnement "RDS_TECHNO_NAME", mais seul "$TOP/etc/cmos_7.rds" à l'air de fonctionner, alors que pour passer vers la couche réelle (.cif : pour la fonderie), il faut utiliser la technologie "$TOP/etc/prol10_7.rds" pour que s2r veuille bien fonctionner. C'est bien ce qui est utilisé dans les tutoriels, mais ça paraît étonnant. En tous cas, elle correspondent toutes les deux à une technologie de 1 micron (voir le mail du CMP à ce sujet : on peut normalement utiliser une technologie CMOS 0.8 micron !). Il faudrait peut-être demander plus de renseignements à l'université de Paris VI, ou au CMP. Notez que le fichier .cif obtenu peut être visionné avec dreal, mais en mettant la bonne valeur dans RDS_TECHNO_NAME (la même qu'avec s2r).

Sommaire

 



Alliance Web Site © 1997, 2002 ASIM/LIP6/UPMC, page maintained by Czo [Olivier Sirol] , last updated on 26 May 2000.