3.3.3 Conception sous ISE du design global «Top »
suivant le Modular Design Flow
A ce stade nous supposons que le module système
à processeur a été testé et validé sous EDK.
Nous rappelons que l'environnement intégré ISE ne permet que la
synthèse des designs dans tout le Modular Design Flow.
Après la création des fichiers sources vhdl et la synthèse
avec XST sous ISE, nous déroulerons les étapes suivantes du
Modular Design Flow par des scripts.
a) Création des codes sources
Les designs (compteurs et clignotants)
destinés au module reconfigurable de gauche peuvent être
écrits, synthétises, placés, routés, testés
et validés individuellement sur le FPGA dans un flot
intégré sous ISE suivant le flow standard Figure, et ce
dans des projets séparés. Ensuite leurs codes sources vhdl
(compteur_lent.vhd, compteur_rap.vhd, clignotant_lent.vhd,
cignotant_rap.vhd, voir annexe 4) sont
rajoutés, chacun a un projet de niveau Top. Chaque projet Top contient
donc le même module fixe (system) et un des designs du module
reconfigurable. Dans ces fichiers sources du module reconfigurable, les
entités doivent porter un nom unique (compteur) et les
mêmes interfaces (entrées/sorties).
Pour les codes vhdl du module fixe (system) et de ses
composantes (IPs), ils ont été
générés par EDK et se trouvent dans le répertoire
hdl du projet EDK. En outre, les fichiers netlists des sous-modules se
trouvent dans le répertoire Implementation du projet EDK et
sont automatiquement ajoutés au projet ISE vers lequel le module fixe
est exporté (sous ISE 6.1.i il faut les ajouter manuellement au projet
ISE).
Pour la création du code source top.vhd, les
étapes préliminaires sont :
- Créer un projet avec Project Navigator [27] de
ISE (ou ouvrir le projet exporté).
- Choisir comme répertoire de travail le même
où le module systeme à processeur (system) validé
a été exporté (répertoire ISE de la Figure
27(a) par exemple).
- Copier le fichier
hdl/system_sub.vhd vers le répertoire ISE de
travail, le renommer top.vhd et y changer le nom de l'entite
system_stub en top. En effet lors de l'exportation du module
system de EDK vers ISE, un fichier system_stub.vhd est
automatiquement généré dans le répertoire
hdl. Ce fichier est un modèle d'instantiation du module
system comme composant d'une entité nommée
system_stub.
- Ajouter au projet le fichier top.vhd.
- A ce niveau, il faut compléter le fichier
top.vhd en y ajoutant le module reconfigurable
(composant compteur) ainsi que ses interfaces (Buffers
I/Os, clk et signaux) de connexion en s'inspirant de l'insertion du module
system.
NB. Les buffers d'entrées/sorties doivent être
ajoutés manuellement dans le fichier top.vhd (voir Etapes de
synthèse ci-dessous).
Dans cette application, les deux modules sont synchrones et
fonctionnent à la même fréquence (voir la distribution
d'horloge aux modules dans le fichier top.vhd, annexe 4. 1).
b) Etape de synthèse des fichiers
sources
Nous avons réalisé la synthèse
incrémentale (voir modular design flow plus haut) des modules
et du Top sous ISE 7.2.i avec l'outil de synthèse XST.
Cette synthèse génère des fichiers de netlist du type
nom_entite.ngc, un pour chaque design du module reconfigurable et un
pour le top (les netlists du module system ayant été
déjà générés sous EDK et ajoutés au
projet ISE). Elle se déroule dans cet ordre :
(i) Synthèse de chaque module ; pour
éviter que XST les instancie dans les modules lors de la
synthèse, les buffers I/O sont désactivés (Synthesize
- Properties - I/O Disabled). En
effet, lors de l'ajout du module reconfigurable dans le
fichier top.vhd, les buffers d'Entrées/Sorties et de clock
doivent être inserrés manuellement comme des composants
(component IBUF/OBUF/IOBUF/BUFGP is...) au niveau top du design, sur
le modèle du fichier system_stub.vhd. La synthèse
génère dans chacun des répertoires les fichiers de netlist
system.ngc et compteur.ngc.
(ii) Synthèse du Top ; l'outil XST fait la
synthèse de la logique globale (connexions inter-modules par bus macros,
connexions entre les modules et les pins externes, etc...), charge
automatiquement les fichiers de netlist (.ngc) de tous les composants
déclarés et instanciés dans le top (modules et Buffers
I/Os et de clock), puis génère le fichier de synthèse du
design complet (top.ngc). Tous les composants déclarés
au niveau Top ont l'attribut « Black_Box » (voir top.vhd
annexe 4.1). Cet attribut indique à XST de ne pas refaire la
synthèse des modules concernés lors de la synthèse du Top,
et de charger directement leur netlist (.ngc).
Pour le Modular Design Flow, Xilinx suggère
une arborescence de répertoires facilitant la lisibilité du
projet [22], les fichiers générés étant très
nombreux et variés. Nous nous en sommes inspirés pour adopter
celle de la Figure 27. Ainsi on a les répertoires et les
projets suivants:
- Le répertoire « ISE » est le
principal répertoire contenant le projet ISE (top.ise) vers lequel
le module system a été exporté
depuis EDK. Il implémente le design Top constitué des modules
system (fixe) et compteur_lent (reconfigurable, avec pour nom
d'entité compteur) et contient les fichiers
générés à la synthèse sous ISE.
- Les répertoires ISE2, ISE3 et ISE4 qui
contiennent chacun une réplique du projet ISE
précédent (top.ise), mais plutôt avec
comme module reconfigurable un design différent (compteur_rap,
cignotant_lent, cignotant_rap) mais de noms d'entité
(compteur) et d'entrées/sorties identiques.
- Le répertoire « HDL_ISE » qui
contient tous les fichiers sources vhdl du top et des designs
(compteur_lent, compteur_rap, cignotant_lent, cignotant_rap)
du module reconfigurable.
- Le répertoire « Modular » dont chaque
sous-répertoire Figure 27.b renvoie à une étape
du
Modular Design Flow et permet de mieux comprendre les
phases d'implémentation des modules et de génération des
bitstreams partiels et total.
Remarque : On peut aussi procéder
autrement en créant un projet ISE unique, en y synthétisant tour
à tour le module fixe et chacun des designs du module reconfigurable, et
en sauvegardant chaque netlist compteur.ngc dans des
répertoires différents en vue d'une utilisation lors de la
phase active d'implémentation. En effet, le modular
design suggère la création de plusieurs projets pour
permettre simplement de générer séparément la
netlist de chaque design (sans Buffer I/Os) en vue de leur
implémentation individuelle, ce que le flot standard ne permet pas.
c) Etape d'Initial budgetting
Apres l'étape de synthèse, l'Initial budgetting
se réalise dans le répertoire
Top/Initial (Figure 27.b) et a pour but de
:
- Déterminer approximativement la taille de chaque
module.
- Attribuer une zone sur la cible pour chaque module à
implémenter.
- Contraindre les I/O du Top communicant avec l'extérieur,
et positionner les BUFG et
BUFGP.
- Positionner toute la logique du niveau Top, spécialement
les Bus macros (bus
d'interconnexion entre modules) qui sont positionnés sur
des TBUFs du FPGA.
En premier on exécute la commande «ngdbuild
-modular initial top.ngc » (voir initial.batch en annexe
4.5) qui prend en entrée la netlist du Top (top.ngc) et la
convertit en un format Xilinx top.ngd.
Ensuite on édite le fichier de contrainte (.ucf)
du projet (voir top.ucf annexe 4.3) . Les outils Constraints
Editor (pour les contraintes de temps) et Floorplanner (pour les
contraintes de placement et de dimensionnement des modules et composants)
permettent d'éditer automatiquement ce fichier. Mais pour la
reconfiguration partielle quelques contraintes spécifiques dont celles
ci-dessous doivent être insérrées manuellement dans le
fichier ucf :
(i) Déclaration du caractère reconfigurable
d'un module
AREA_GROUP "AG_nom_instance_module" MODE = RECONFIG;
Tous les modules sont en mode RECONFIG qu'ils soient
reconfigurables ou fixes.
(ii) Contrainte de placement des bus macros
INST "nom_instance_bus_macro" LOC = "TBUF_X56Y24" ;
[28] est le document de référence pour
l'édition des fichiers de contrainte.
Il est à noter que des broches du FPGA sont
physiquement connectés à des périphériques (SRAM,
LEDs, SDRAM 32Mo, Ethernet, RS-232, etc...Figure 25) présents
sur la carte de développement. La position et la dimension d'un module
sur le FPGA sont donc fortement dépendant du périphérique
auquel on souhaite le connecter. C'est ainsi que nous n'avons pas pu utiliser
la SDRAM 32 Mo présente sur la carte comme mémoire de stockage
des bitsreams, car elle est connectée au FPGA par les broches du
côté gauche, opposé au côté du système
à processeur. Dans tous les cas, éditer un fichier de contrainte
dans une application comme celle-ci se fait en grande partie manuellement, et
demande une bonne connaissance de la carte de développement
utilisée. Pour la carte Memec Design Virtex-II ProTM, nous
avons conjointement utilisé [24] et [29]. Il en a resulté le
fichier top.ucf en annexe 4.3.
d) Etape d'Active Module
Implémentation
Chaque design est implémenté
séparément dans un sous-répertoire d'implémentation
se trouvant chacun dans le répertoire Modules
(par exemple Modules/compteur_rap, Figure 27.b). Pour
implémenter chaque design, on utilise en entrée son fichier
<nom_entité_module.ngc> généré lors
de la synthèse ainsi que les fichiers .ucf et .ngc du
Top. Ces fichiers doivent donc être dans le
sous-répertoire d'implémentation courant du design. Pour le
module system, tous les fichiers .ngc de ses composantes
(fichiers xxx_wrapper.ngc, etc) doivent également être
recopiés dans son répertoire d'implémentation.
La phase active nécessite plusieurs commandes (voir
fichiers active.batch annexe 4.5):
- NGDBUILD lancée en mode actif pour chaque design dans
son sous-répertoire
d'implémentation et qui génère le fichier
.ngd du module.
ngdbuild -modular module -active <nom_entite_module>
-uc top.ucf top.ngc
- MAP et PAR qui font le Placement et Routage du module à
partir du fichier .ngd généré
plus haut.
map < nom_entite_module.ngd> par -w <
nom_entite_module.ncd>
- PIMCREATE qui crée un sous-répertoire par module
dans le répertoire PIMS
(Physically Implemented Modules, Figure 27.b) et y
publie tous les fichiers décrivant l'implémentation physique du
module ;
pimcreate -ncd « nom_entite_module.ncd »
..\..\Pims
Ces informations servent lors de l'assemblage final du Top
(Final Assembly). Tous les designs du module reconfigurable ayant des
I/Os identiques, il n'est pas nécessaire de lancer cette commande pour
chacun de ces designs, car elle publierait les mêmes informations.
- BITGEN permet de générer le bitstream partiel
(fichier .bit). L'option -g ActiveReconfig
permet la reconfiuration dynamique. L'option -d est
utilisée pour ne pas lancer DRC (Design Rule Check) lors du bitgen, et
l'option -b permet de générer la version ASCII du
fichier bitstream. Cette version est plus facile à manipuler et à
stocker dans la mémoire SRAM de la carte en vue de la reconfiguration
dynamique.
Remarque : Avant la phase active d'un module, son
fichier .ngc et celui de ses composantes (cas du module system
avec ses composantes xxx_wrapper.ngc, etc..) doivent être
recopié dans son sous-répertoire d'implémentation, ainsi
que les fichiers .ucf et . ngc du top.
e) Etape de Final Assembly (annexe
4.5)
Cette phase finale sert à assembler tous les modules
indépendamment implémentés dans un design Top
unique (voir fichiers assemble.batch annexe 4.5). Tous les modules
sont ainsi placés et routés dans un design Top unique,
puis le bitstream complet est généré. Les commandes
d'assemblage sont exécutées dans le répertoire
Top/Assemble (figure 27b) et utilisent les fichiers
publiés en phase précédente dans les
sous-répertoires du répertoire PIMS. Les commandes sont
identiques à celles utilisées en phase active pour
implémenter les modules (voir fichier assemble.batch en annexe
4.5), la commande Pimcreate en moins. La difference majeure vient des
options utilisées.
Lors du BITGEN on doit avoir l'option -g
startupclk:jtagclk pour s'assurer que le FPGA démarrera sur le
clock du Jtag après configuration. L'option -d n'est pas utilisée
en phase d'assemblage. L'option -b également (on n'a pas besoin de la
version ASCII du fichier bitstream). Le fichier bistream
généré permet de configurer le FPGA.
On peut souhaiter faire plusieurs assemblages afin de
générer plusieurs bitstreams complets (par exemple on peut
associer compteur_lent et system dans Assemble/Top, et
associer cignotant_lent et system dans Assemble/Top1).
Remarque :Pour reconfigurer partiellement le FPGA, il faut au
préalable l'avoir programmé avec un bitstream total.
f) Etape de
génération du bitstream final
Apres la phase d'assemblage (voir repertoire Top/Assemble), le
fichier bitstream (assemble.bit et/ou assemble.rbt) permettant de reconfigurer
les ressources logiques (CLBs, BRAMs, etc...) du FPGA est
généré. Mais pour notre application qui comporte en outre
une partie logicielle a exécuter sur le processeur embarqué, il
convient:
- de configurer les ressources logiques du FPGA (avec le fichier
bitstream de la phase
d'assemblage).
- de charger l'exécutable destiné au processeur
PPC405 en mémoire de programme
du processeur et d'initialiser ce dernier.
Ce dernier point nécessite :
- le fichier executable.elf produit suivant les phases
de développement décrites plus
haut (création de la plate-forme logicielle), et
- un fichier.bmm (system.bmm pour
l'entité system) indiquant les coordonnées
exactes des BRAMs (ressources FPGA) qui ont été
associées au processeur via le bus PLB lors de la phase
d'implémentation active du module fixe (système
à
processeur) ; en effet c'est dans cette mémoire
que seront chargés le code de démarrage du processeur ainsi que
l'exécutable de notre application.
Le fichier .bmm est édité manuellement,
les outils ne permettant pas encore sa génération automatique.
Les coordonnées des BRAMs associés au processeur sont obtenus en
éditant avec l'outil FPGA Editor le design placé et
routé (phase d'implémentation active) du module «
système à processeur » et en répérant
lesdites coordonnées dans une des fenêtres indiquant le placement
des composants instanciés dans le FPGA. On peut aller plus vite en
complétant simplement le fichier system_stub.bmm se trouvant
dans le répertoire Implementation. L'annexe 2 détaille
avec un exemple visuel les étapes de création du fichier
.bmm.
En annexe 4.5 se trouve la ligne de commande permettant
d'associer un fichier .bmm nomme
system, un fichier
bitsream_complet.bit et un fichier
executable.elf pour générer un fichier
unique (chargement.bit) permettant de configurer totalement le FPGA et
démarrer le processeur.
|