1
CHAPITRE 3
Simulation et synthèse
3.1 Introduction
Les langages de description matérielle (Hardware Description Language (HDL)) tels que VHDL
ou Verilog servent à la simulation et à la synthèse d’un modèle matériel. La simulation sert à
déterminer d’une part que la description comportementale du circuit est fonctionnellement
correcte. D’autre part, elle sert à vérifier le bon fonctionnement de la description synthétisée du
circuit en tenant compte des délais introduits par les cellules de base. La synthèse sert à
transformer la description HDL en une description de primitives (NAND, NOT, NOR et cellule
complexe) de façon à être interprétée automatiquement par des outils de placement et de routage
pour la création de dessin de masques.
Dans le cadre du cours ELE4304, nous allons utiliser le simulateur logique ModelSim de Mentor
Graphics et l’outil de synthèse logique design_vision (dc_shell) de Synopsys. Dans ce document,
une introduction à l’utilisation de ces outils sera présentée et des pointeurs vers la documentation
complète seront donnés. Ce document présente dans l’ordre :
L’utilisation de ModelSim pour la simulation fonctionnelle (simulation pré-synthèse);
La synthèse logique avec design_vision;
L’utilisation de ModelSim pour la simulation temporelle (simulation post-synthèse).
3.2 Simulation Fonctionnelle
Une fois le code ou les codes VHDL écrits, ils devront être compilés et un banc d’essai ou
“testbench” en VHDL devra être écrit afin de vérifier le bon fonctionnement de votre circuit. Un
“test-bench” est une description VHDL qui utilise le circuit à simuler comme un composant
(description structurelle) et donne un certain comportement aux signaux d’entrées (description
comportementale).
Dans la suite de cette section, nous avons implémenté le design d’un compteur dont le code est
donné à la Figure 1.
-- Fichier : compteur_bcd10.vhdl
-- Description : Compteur BCD de 0 a 9
library ieee; -- On inclu la librairie IEEE
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
entity compteur_bcd10 is -- définition des entrées/sorties
port(clk, en, rst_n : in std_logic;
rco : out std_logic;
q : out std_logic_vector(3 downto 0));
end compteur_bcd10;
architecture behav of compteur_bcd10 is
signal cnt : std_logic_vector(3 downto 0); -- signal interne
begin
q <= cnt; -- q, la sortie vaut la valeur du compte actuel en tout temps
process(clk, rst_n) -- process sensible à l’horloge et au “clear”
begin
2
if (rst_n='0') then -- “clear” asynchrone
cnt <= (others => ‘0’);
rco <= '0';
elsif (clk'event and clk='1') then -- au front montant
if (en='1') then -- si enable est à 1
if (cnt = “1010“) then -- si on atteint 9 on fait un rco
cnt <= (others => ‘0’);-- et on remet le compteur a 0
rco <= '1';
else -- sinon on compte
cnt <= cnt + “0001“;
rco <= '0';
end if;
else
cnt <= cnt;
rco <= ‘0’;
end if;
end if;
end process;
end behav;
Figure 1. Code du Compteur : compteur_bcd10.vhdl
Le testbench qui a été proposé pour tester notre compteur est donné à la Figure 2
library IEEE;
library WORK; -- Cette librairie permet d’accéder à notre design compteur
use IEEE.std_logic_1164.all;
use WORK.all;
ENTITY test_bench IS
END test_bench;
ARCHITECTURE test_cntbcd10 OF test_bench IS
COMPONENT compteur_bcd10 -- définition des entrées/sorties
port(clk, en, rst_n : in std_logic;
rco : out std_logic;
q : out std_logic_vector(3 downto 0));
END component ;
SIGNAL clk : std_logic:= '0'; -- initialisation de lhorloge
SIGNAL rst_n,en,rco: std_logic;
SIGNAL q: std_logic_vector(3 downto 0);
constant CLK_PERIOD : time := 200 ns;
BEGIN
test_compteur_bcd10: compteur_bcd10 PORT MAP(clk=>clk,en=>en,rst_n => rst_n,
q=>q,rco=>rco);
--Signal dhorloge
clk <= not clk after CLK_PERIOD;
test : process
begin -- process test
en <='0';
rst_n <='0';
wait for 4*CLK_PERIOD;
rst_n <= '1';
wait for 5*CLK_PERIOD;
en <='1';
wait for 25*CLK_PERIOD;
en <='0';
wait for 5*CLK_PERIOD;
rst_n <='0';
wait;
end process test;
END;
-- Code optionnel
CONFIGURATION cfg_comptbcd10_tb OF test_bench IS
FOR test_compteur_bcd10
END FOR;
END cfg_comptbcd10_tb;
Figure 2. code du testbench du compteur : compteur_bcd10_tb.vhdl
3
Comme nous l’avons dit précédemment, le simulateur ModelSim de la compagnie Mentor
Graphics sera utilisé pour effectuer toutes les simulations fonctionnelles.
La première opération à effectuer avant d’utiliser ModelSim est d’initialiser votre environnement
en tapant la commande suivante sous votre fenêtre « gnome-terminal » :
…% stmodelt
Ensuite, vous devez créer une librairie, généralement elle se nomme : « work ». La commande
suivante permet de créer la librairie :
…% vlib work
Après la création de la librairie, les fichiers « vhdl » peuvent être compilés. La commande en
ligne pour compiler un fichier est la suivante :
…% vcom nom_fichier1.vhdl nom_fichier2.vhdl
Il faut préciser que toutes les commandes présentées ci-avant peuvent être effectuées sous
l’environnement graphique de ModelSim.
À partir de maintenant vous pouvez ouvrir l’environnement graphique, en tapant la commande
suivante :
…% vsim&
La première fois, vous devrez créer un projet, l’outil vous le demandera automatiquement. Les
prochaines fois, vous pourrez créer un nouveau projet à partir du menu « file ». Il faudra faire
attention, car il faut préciser la location du répertoire dans lequel le projet sera créé. Comme le
montre la Figure 3, si la librairie par défaut n’existe pas, il la créera automatiquement.
Figure 3. Création d’un projet dans ModelSim
Après avoir cliqué sur « OK », l’outil vous demandera si vous voulez créer un fichier « vhd » ou
en insérer un déjà existant. Généralement vous avez déjà écrit votre code, donc vous avez juste à
insérer vos fichiers. Sinon, vous pouvez quitter cette option et cliquer sur l’onglet : « File » (voir
la barre de menu en haut) et sélectionner l’option « Add to Project/existing file » pour ajouter
des fichiers à votre projet.
Vous pouvez compiler vos fichiers si ce n’est pas déjà fait, en cliquant sur l’onglet « Compile »
de la barre de menu, et faire votre choix entre « Compile Selected » ou «Compile All », comme
le montre la Figure 4.
4
Figure 4. Compilation de fichiers
Après la compilation de tous les
fichiers, vous pouvez charger la
configuration de votre design en
cliquant sur l’onglet « Simulate »
option « Start Simulation ». Une
fenêtre comme celle illustrée à la
Figure 5 s’ouvrira et vous devrez
sélectionner la configuration du
design (il s’agira du banc d’essai).
La commande qui suit, permet
aussi de charger un design :
%vsim
nom_lib.nom_configuration
L’option « Resolution » permet de
sélectionner l’unité de mesure
temporelle (fs, ns, etc) pour la
simulation.
Figure 5. Chargement d’un design
Après le chargement du design une fenêtre, comme celle illustrée par la Figure 6, s’ouvrira.
Comme vous pouvez le remarquer deux nouveaux onglets ont été ajoutés au bas de la fenêtre :
« sim » et « Files ».
5
Figure 6. Fenêtre principale après le chargement du design
Le premier énumère tous les designs qui entreront en jeu durant la simulation et le second, retrace
tous les fichiers « vhdl » utilisés par le design.
L’avant dernière étape avant la simulation consiste à insérer les signaux à visualiser dans le
diagramme de simulation. Cliquez sur le design avec le bouton de droite de la souris et
sélectionner les options suivantes : « Add/add to Wave ». Cette opération fera apparaitre la
fenêtre des signaux et ajoute tous les signaux de l’architecture sélectionnée dans la fenêtre
« wave ». Il vous est possible d’agrandir (« + ») ou d’ouvrir dans une fenêtre séparé (« flèche »)
les chronogrammes.
Figure 7. Fenêtre principale après le « add/add top wave »
Pour raison de visibilité, il vous est recommandé d’avoir la fenêtre séparée. Cela vous donne
accès à certaines options de la fenêtre de signaux. Entre autre, afin de bien visualiser le nom des
6
signaux, vous pourrez ainsi sélectionner « Tools/Windows Preferences ». Et ensuite, vous
indiquez ‘1’ pour « Display Signal Path ». Cela vous permettra d’éviter d’avoir tout le chemin
hiérarchique du signal.
Figure 8. Enregistrement des préférences pour la fenêtre « wave »
Après avoir ajouté tous les signaux dans le diagramme, il est conseillé de sauvegarder ce format :
cliquez sur le menu « File/Save » de la fenêtre « wave ». Ainsi, votre diagramme de simulation
sera préservé pour de prochaines simulations. Il suffira d’ouvrir la fenêtre « wave » et de charger
le fichier que vous venez sauvegarder (Load Format).
Maintenant vous pouvez démarrer la simulation de 2 manieres :
- Taper la commande : « run durée_simulation » dans la fenêtre principale;
- Cliquer sur une des icônes illustrées par la Figure 9 de la fenêtre de diagrammes.
7
run
run continue run all Break
Figure 9. Quelques icônes à connaître dans la fenêtre de diagrammes
Pour sauvegarder les traces résultantes de la simulation, il vous suffit de cliquer sur :
« File/Export/Image » et une image en format « bmp » sera sauvegardée. Vous pourrez utiliser
le programme GIMP pour re-sauver cette image en format « png » plus compacte. Si vous voulez
sauvegarder tout le diagramme, il faudra sélectionner l’option « print » et le sauvegarder dans un
fichier en format postscript.
Si vous avez effectué des modifications dans un de vos fichiers « vhdl », vous devez le
recompiler ainsi que tous les fichiers qui en dépendent. Il faut aussi redémarrer la simulation en
cliquant sur l’onglet : « Simulate/run/restart » de la fenêtre principale.
Si vous avez à modifier vos fichiers vhdl, vous pouvez le faire a partir de Modelsim en cliquant
sur le fichier. Si vous estimez que cette option est lente à utiliser, vous pouvez utiliser un autre
éditeur de texte tel que « gedit » ou « emacs ». Par exemple, vous pouvez entrer
« gedit nom_du_fichier & » dans une fenêtre gnome-termimal pour ouvrir un fichier spécifique.
Pour décharger une simulation vous pouvez:
- Taper la commande : quit –sim
- Ou, cliquer sur l’option « Simulate/end Simulation » de la barre de menu de la
fenêtre principale.
Lorsque vous aurez fini, cliquez sur : « File/Quit » pour fermer ModelSim.
Si vous désirez en savoir plus sur les commandes de ModelSim, vous pouvez consulter les
fichiers d’aide se trouvant dans le répertoire :
/share/peel/10/packages/modeltech_6.0c_32bit/docs/
Plus particulièrement les fichiers suivants du répertoire pdf : se_tutor.pdf et se_cmds.pdf.
Vous pouvez ouvrir un fichier pdf sous un environnement Linux/Unix à l’aide de la commande
« acroread » ou « evince ».
8
3.3 Synthèse Logique
Tapez dans une fenêtre gnome-terminal la commande pour initialiser l’environnement afin de
pouvoir utiliser les outils de Synopsys:
% stsyn
Assurez-vous également d’avoir le fichier de configuration (dotfiles) (fichiers cachés) suivants:
.synopsys_dc.setup
Vous pouvez le vérifier en tapant la commande suivante:
% ls -a ~/
Si vous n’avez pas ce fichier, vous pouvez copier l’exemple qui se trouve à la racine de votre
répertoire de travail. Ce fichier indique à Synopsys les chemins des librairies associés aux
technologies.
% cp ~/.synopsys_dc.setup .synopsys_dc.setup
Pour les besoins du cours, assurez vous que ce fichier soit similaire à l’exemple qui suit.
9
Au début de ce fichier, vous avez un ensemble les définitions de link_library, target_library et de
physical_library. Ensuite, vous avez une liste qui définit votre répertoire de travail :
design_design_lib work –path Work
Donc, vous devez créer le répertoire Work à l’endroit où vous utiliserez l’outil de synthèse.
% mkdir Work
En principe vous n'allez pas avoir besoin de modifier le fichier .synopsys_dc.setup que nous
vous avons fourni.
Nous allons donner un exemple qui vous servira d’apprentissage. Nous voulons réaliser un
compteur bcd 0 à 9 dont la description VHDL est donnée à la Figure 3.1.
Supposons que nous avons un répertoire de travail “compteur” qui contient le fichier
“compteur_bcd10.vhdl” (voir Figure 1). D’une fenêtre gnome-terminal, et dans le répertoire
“compteur”, tapez:
% design_vision (n’oubliez pas d’initialiser d’abord l’environnement avec stsyn)
Pour compiler cette description VHDL, il suffit de:
1 - Choisir la fonction Analyse du menu File, une fenêtre Analyze File apparaîtra;
2 - Taper (ou sélectionnez) le nom du fichier VHDL pour File Name; (il est possible de
sélectionner plusieurs fichiers à analyser en même temps avec le « shift » du clavier)
3 - Choisir VHDL pour File Format, sélectionner la librairie “DEFAULT” pour Library;
4 - Cliquer sur OK. Une fenêtre Analyze apparaîtra pour les messages d’erreurs;
5 - Une fois la compilation terminée, exécuter la procédure Elaborate du menu File pour faire
apparaître la fenêtre Elaborate Design.
6 - Sélectionner “DEFAULT” pour Library, “compteur_bcd10” pour Design et cliquer sur OK.
Pour voir le symbole du design, sélectionner le module dans la colonne « Logical Hierarchy » et
cliquez sur le boutton « Create Symbol View ». La synthèse avec la procédure “Elaborate”
donne un circuit au niveau symbole et non au niveau porte. On peut voir à l’intérieur du symbole
en double-cliquant sur celui-ci. (voir Figure 10 ci-dessous)
10
Figure 10. Fenêtre de design_vision
Si le design est composé de plusieurs modules, vous devrez éliminer les modules en sélectionnant
chaque module et en utiliser la commande ungroup (Hierarchy->ungroup).
Voyons maintenant les opérations à réaliser pour faire la synthèse au niveau des portes:
Si le design est séquentiel, il faut spécifier les cycles d’horloges (Attributes-> Specify Clock) et
le type de bascule qu’on veut utiliser (optionnel) (Attributes-> Optimization Directives->
Design) avant de faire la synthèse au niveau des portes. Pour effectuer la synthèse, il faut :
1. Se placer la vue au niveau du symbole et cliquer sur l’entrée “clk” afin de la sélectionner;
2. Choisir l’option (Attributes-> Specify Clock). Pour ce design la période de l’horloge sera
fixée à 200 ns, tapez donc 200 dans la case Period et cliquez ensuite sur Apply suivi de OK
pour effacer la fenêtre;
3. Si votre design instancie plusieurs fois la même composante, vous aurez à utiliser la
commande (Hierarchy -> uniquify) pour donner un nom unique à chacune.
11
4. Si votre module contient des sous-modules, il vous est possible de faire un « ungroup » afin
d’éliminer les sous modules pour la synthèse. Il s’agit de sélectionner les sous-modules sur
l’interface graphique de design_vision et faire l’option Hierarchy -> ungroup;
5. Après avoir sélectionné le module à synthétiser, exécuter la procédure Compile Design du
menu Design. On utilise les paramètres par défaut. Cliquer sur OK et patienter quelques
instants;
Le circuit optimisé devra être ensuite enregistré. Vous pouvez enregistrer le netlist sous plusieurs
formats, vous devrez enregistrer le netlist en format Verilog sous le nom de
“compteur_bcd10.netlist.v”. Ce fichier servira plus loin à la simulation temporelle. Exécutez la
fonction “Save As” du menu “File”, taper “compteur_bcd10.netlist.v” pour File Name, choisir
Verilog pour File Format et cliquez sur OK. Notez que le format par défaut, DB, est le netlist au
niveau des portes.
Finalement, vous devez enregistrer la spécification des délais. Ce fichier servira plus loin à la
simulation temporelle. Dans la ligne de commandes de Design Vision, exécutez :
« write_sdf compteur_bcd10.timing.sdf ».
Pour produire des estimations sur les ressources utilisées pour l’implémentation du design, vous
pouvez utiliser la commande Design->Report Area. Celle-ci vous donnera une estimation de la
surface requise par le design. Pour une analyse temporelle statique vous n’avez qu’à sélectionner
l’option Timing->Report Timing Path. Pour les designs séquentiels assurez-vous d’avoir
attribué une période d’horloge au circuit (Attributes-> Specify Clock).
design_vision est en fait une interface graphique servant à exécuter des commandes de plusieurs
outils de Synopsys. Pour voir, les commandes exécutées pour design_vision, il suffit de voir
l'onglet « History » dans la command window au bas.
Pour imprimer des schémas de vos circuits :
1. Placez-vous maintenant dans la vue que vous désirez imprimer (symbole, portes, etc.) et
utilisez les options View -> Zoom->... afin de voir tout le design.
2. Faites maintenant File -> Print Schematic. Dans la fenêtre de dialogue, sélectionnez
l'imprimante à utiliser, ou choisissez l’option « Print to file » et donnez un nom au fichier
postscript qui en résultera. Vous pouvez utiliser l'outil « GIMP » pour convertir un fichier
postscript vers n'importe quel autre format (png, gif, jpeg, ...).
12
3.4 Simulation temporelle
Dans la section 3.2, nous avons simulé la description comportementale du “compteur_bcd10”.
Dans ce qui suit, nous allons simuler le circuit et non la description. La simulation ainsi obtenue
tient compte des délais dans les différentes portes. C’est avec cette simulation que l’on sait
vraiment si notre design est fonctionnel. Pour faire cette simulation, il suffit d’utiliser le fichier
compteur_bcd10.netlist.v, généré précédemment lors de la synthèse, et le même « test bench ». Il
faut d’abord s’assurer de respecter l’ordre de compilation des fichiers. Vous pouvez insérer le
fichier netlist à votre projet (File ->add to project -> existing file) et ensuite modifier l’ordre de
compilation des fichiers (compile -> compile order) en vous assurant de compiler votre netlist
juste avant le banc d’essai. Vous pouvez ensuite recompiler vos fichier avec le nouvel ordre de
compilation. Il est à noter que vous pouvez également compiler le fichier Verilog avec la
commande suivante (deuxième alternative) en vous assurant de recompiler votre banc d’essai
uniquement par la suite dans ModelSim:
% vlog compteur_bcd10.netlist.v
Notez que si vous avez des paramètres génériques, le nom de votre composante appelée par le
banc d’essai doit être modifié pour le nom du module généré par design_vision. Vous pouvez
ouvrir le fichier netlist (verilog) pour observer le nom du module qu’il définit. Ensuite, vous
devez utiliser modelsim tel qu'exposé à la section 3.2. Toutefois, vous devez préalablement
réaliser les tâches suivantes:
Chargement du Banc d'essai
Vous devez charger le banc d'essai en utilisant la fonction Start Simulation du menu Simulate.
Sous l'onglet Design, choisissez l'entité du banc d'essai (ou une configuration si vous en avez
définie une) et fixez Resolution à ps.
Figure 11. Fenêtre Simulate : Design
13
Ensuite, allez sous l'onglet Librairies et cliquez sur Add pour donner le chemin de la Librairie
des cellules normalisées tel qu’exposé à la Figure 12 et 13. Choisissez la dernière version
(modelsim62c pour ce lab).
Figure12. Fenêtre pour donner le chemin de la Librairie
14
Figure 13. Fenêtre Simulate : Librairies
Ensuite, allez sous l'onglet SDF. Appuyez sur Add et sélectionnez le fichier SDF que vous avez
généré lors de l'étape de synthèse. Vous devez aussi spécifier le chemin de l'instance sur laquelle
s'applique les spécifications des délais (voir figure 14). La Figure 15 expose un exemple d’un
compteur pour lequel le fichier SDF s'applique à l'instance /test_bench/test_compteur_bcd10.
Soit le nom de l’entité du banc d’essai (test_bench) suivit du nom de l’instanciation de la
composante synthétisé dans le banc d’essai (test_compteur_bcd10 est l’instanciation d’une
composante compteur_bcd10).
Figure 14. Fenêtre de sélection du fichier SDF et de l’instance
Figure 15. Fenêtre Simulate : SDF
15
Appuyez sur OK et maintenant la simulation temporelle est prête à partir de la même façon qu'à
la section 3.2. Comme on peut le voir à la Figure 16, il y a des glitchs que l'on peut observer en
grossissant suffisamment la fenêtre. Vous pouvez le faire avec le bouton central de la sourie ou en
utilisant l’option « view/zoom/zoom in » de la fenêtre de signaux.
Figure 16. Chronogrammes avec glitchs